package com.sundog.sundroid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.sundog.sundroid.google.GoogleService;
import com.sundog.sundroid.google.SheetInfo;
import com.sundog.sundroid.testclasses.VotingSimulator;

/**
 * This activity is displayed between voting rounds and displays voting status and results
 * 
 * @author Matt Smith
 *
 */
public class ResultsWaitingScreen extends Activity {
	
	/** Represents this particular class instance */
	private ResultsWaitingScreen screen = this;
	/** Represents this particular context */
	private Context context;
	/** Boolean to determine if a message has been received */
	private boolean messageReceived = false;
	/** User map */
	private static Map<String, String> users;
	/** User array */
	private static String [] userNames;
	/** Vote map */
	private Map<String, String> votes = new HashMap<String, String>();
	/** Spreadsheet ID */
	private static String id = "";
	/** View for displaying votes */
	private ArrayList<TextView> voteList = new ArrayList<TextView>();
	/** Screen layout */
	private TableLayout tl;
	/** Layout for individual votes */
	private TextView child;
	/** Determines if a revote message has been received */
	private boolean revote = false;
	/** Resolved vote */
	public static String resolveResult;
	/** Create a packet filter to receive messages of type Message */
	PacketFilter filter = new PacketTypeFilter(Message.class);
	
	/** Create a packet listener to process messages */
	PacketListener myListener = new PacketListener() {
	
		/** Method for processing messages */
		public void processPacket(Packet packet) {
		
			Message msg = (Message) packet;
			voteHandler(msg);
       }};
    
    /** method for handling incoming votes */ 
    private void voteHandler(Message msg) {
    	
    	// Scan incoming messages for tags and process them accordingly
    	Scanner scan = new Scanner(msg.getBody());
		scan.useDelimiter(":");
    	if(msg.getBody().equalsIgnoreCase("Revote")) {
    		connection.disconnect();
    		this.finish();
    		
    	} else if(scan.next().equalsIgnoreCase("Resolve")) {
    		
    		resolveResult = scan.next();
    		Intent i = new Intent(this, ResolveScreenUser.class);		
			startActivity(i);
			Log.d("***", "result is resolved " + resolveResult);
			connection.disconnect();
			screen.finish();
			Log.d("***", "Resolve result is " + msg.getBody() + " from " + msg.getFrom());
    	}

		// Create a scanner and parse the user name from the message 
		Scanner in = new Scanner(msg.getFrom());
		in.useDelimiter("/");
		String user = in.next();
		Log.d("USER", user);
		
		// Update the users vote
		votes.put(user, msg.getBody());
		
		// If all users have voted, update the vote list to display actual vote values
		if(!votes.containsValue("-1")) {			

			// Update vote list to contain actual vote values
			voteList = new ArrayList<TextView>();
    		for(String s : votes.keySet()) {
    			
    			TextView tv = new TextView(context);
    			tv.setText(s + "......." + votes.get(s));
    			voteList.add(tv);
    		}
    		
    		// Add user votes to a new table layout
    		tl = new TableLayout(context);
    		for(TextView t : voteList) {
				tl.addView(t);
				Log.d("***", "Child added thrice");
			}
    		revote = true;
    	} 
		// If some users still haven't voted, update the vote list to show who still needs to vote			
		else {
    		// Update what is going to be displayed on the screen
    		voteList = new ArrayList<TextView>();
    		for(String s : votes.keySet()) {
    			TextView tv = new TextView(context);
			
    			if(votes.get(s) == "-1") {
    				tv.setText(s + ".......###");
    				voteList.add(tv);
				
    			} else {
    				tv.setText(s + ".......Voted");
    				voteList.add(tv);
    			}
    		}
		
    		// Add updated vote list to a new table layout
    		tl = new TableLayout(context);
    		for(TextView t : voteList) {
    			tl.addView(t);
    			Log.d("***", "Child added 21");
    		}
    	}
		// Update UI to reflect changes
		mHandler.post(mUpdateResults);
    }
    
	/** Connection configuration for XMPP messaging */
	private final ConnectionConfiguration connConfig =
		 new ConnectionConfiguration("talk.google.com", 80, "jabber.org"); 
	/** Establishes XMPP connection using the connection configuration */
	private final XMPPConnection connection = new XMPPConnection(connConfig);
	
	/** Thread to listen for messages */
	private final Thread t = new Thread() {
        public void run() {
        	
       		try {
       			Thread.sleep(5000);
       		} catch(InterruptedException e) {
       			Log.d("ERROR", "Thread exception" + e.getMessage());
       		}	

    		// Continue execution until voting round is over
        	while(!revote) {
        		try {
                	Thread.sleep(5000);
                }
                catch(InterruptedException e) {
                	Log.d("ERROR", "Thread exception" + e.getMessage());
                }
        	}
        	try {
            	Thread.sleep(5000);
            }
            catch(InterruptedException e) {
            	Log.d("ERROR", "Thread exception" + e.getMessage());
            }
        }
    };
	
    // Handler for call backs to the UI thread 
    final Handler mHandler = new Handler(); 

    // Create runnable for posting UI updates 
    final Runnable mUpdateResults = new Runnable() { 
        public void run() { 
        	updateResultsInUi();   
        } 
    }; 
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.resultswaitingscreen);
		
		// Connect to the XMPP server
    	connectToServer();
		
    	// Initialize variables
		tl = new TableLayout(this.getApplicationContext());
		child = new TextView(this.getApplicationContext());
		context = this.getApplicationContext();
		
		initializeUserList();
		
		// Simulate vote from demosundog
		Message mess = new Message();
		mess.setBody(this.getIntent().getExtras().getString("userVote"));
		mess.setTo("demosundog@gmail.com");

		Log.d("MESS", "From " + mess.getFrom());
		Log.d("MESS", "To " + mess.getTo());
		Log.d("MESS", mess.getBody());
		connection.sendPacket(mess);
		
		connection.addPacketListener(myListener, filter);

		Message msg = new Message();
		msg.setBody(this.getIntent().getExtras().getString("userVote"));
		msg.setFrom("sundroiddemo@gmail.com/");
		voteHandler(msg);		

		t.start();
	}
	
	/**
	 * Refresh the screen after a change to it has been made
	 */
	private void updateResultsInUi() {
		this.setContentView(R.layout.resultswaitingscreen);
		this.addContentView(tl, new TableRow.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
	}
	
	/**
	 * Initialize initial user list state
	 */
	private void initializeUserList() {
		// Retrieve spreadsheet ID
		id = this.getIntent().getStringExtra("SID");
		
		// Retrieve the list of users from the spreadsheet
		users = GoogleService.returnUserList(id);
		userNames = users.keySet().toArray(new String[users.size()]);

		// Set initial votes to -1
		for(String s : userNames) {
			
			TextView child2 = new TextView(this.getApplicationContext());
			votes.put(s, "-1");
			child2.setText(s + ".......###");
			voteList.add(child2);
		}
		
		// Add each vote to the vote list
		for(TextView t : voteList) {
			tl.addView(t);
			Log.d("***", "Child added");
		}

		// Add the vote list to the screen
		this.addContentView(tl, new TableRow.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
	}
	
	/**
	 * Set up a connection to the Jabber server
	 */
	private void connectToServer() {
		try {	
			// Connect to the server if not already connected and log in with user name and password from previous activity
			if(!connection.isConnected()) {
				Log.d("***", "User Connect results...");
				connection.connect();
				connection.login("sundroiddemo@gmail.com", "sundog101");
				Log.d("***", "User Connected results");
			}
		} catch (XMPPException e) {
			Log.d("***", "XMPPException" + e.getMessage());
		}
	}
}
